#ifndef FND_GAME_2D_GRAPH_HPP
#define FND_GAME_2D_GRAPH_HPP
#include <boost/config.hpp>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
//#include <sfml/system.hpp>
#include "mover.hpp"
//#include "tile_image.hpp"
namespace boost {
  enum vertex_pic_t {vertex_pic = 32980,} ;
  enum vertex_weight_t {vertex_weight = 454102,} ;
  BOOST_INSTALL_PROPERTY(vertex,weight) ;
  BOOST_INSTALL_PROPERTY(vertex, pic) ;

}
namespace FndGame2D {
  typedef boost::property<boost::vertex_index_t, int,
			  boost:: property<
    boost::vertex_weight_t, float,
    boost::property<boost::vertex_pic_t, std::string> > >
  vertex_p ;
  typedef boost::property<boost::edge_weight_t, float> edge_p ;
  typedef boost::adjacency_list<boost::vecS,
				boost::vecS,
				boost::undirectedS,
				vertex_p,
				edge_p,
				boost::no_property > game_graph_t ;
  class game_map_mover ;
  class tile_image ;
  class game_graph : public mover{
  public:
    static const std::string SET_BACK_IMAGE ;
    game_graph(const std::string& name = std::string(), int draw_level = 0,
	       const mover::position_type& pos =  mover::position_type(),
	       float angle = 0.0f) ;
    ~game_graph() {
      if(m_draw_back_sprite) delete m_draw_back_sprite ;
      m_draw_back_sprite = 0 ;
    }
  private:
    game_graph_t* m_graph ;
  public :
    bool create_graph_from_file(const char* file_name) ;
    game_graph_t* get_graph() {return m_graph ;}
  private:
    bool handle_load_map_from_file_message(const normal_thinker_message_type& msg) ;
    bool handle_set_tile_image_message(const normal_thinker_message_type& msg) ;
    void test_render(sf::RenderTarget& target) ;
    void init_map() ;
    sf::Shape m_circle ;
    int m_width ;
    int m_height ;
    int m_tile_size ;
    typedef std::vector<boost::graph_traits<game_graph_t>::vertex_descriptor> pos_vec ;
    typedef std::vector<game_map_mover*> buddy_map_type ;
    buddy_map_type m_buddies ;
    pos_vec m_processors ;
    pos_vec m_valid ;
    std::vector<float> m_distances ;
    int m_current_x ;
    int m_current_y ;
    bool m_is_holding ;
    bool m_is_need_fix_road ;
    sf::Image* m_back_tile ;
    sf::Sprite* m_draw_back_sprite ;
    tile_image* m_tile_image ;
    game_map_mover* m_current_valid_buddy ;
  private:
    game_map_mover* find_valid_buddy() ;
    bool handle_set_tile_size_message(const normal_thinker_message_type& msg) ;
    bool handle_set_back_tile_image_message(const normal_thinker_message_type& msg) ;
    bool handle_fix_road_message(const normal_thinker_message_type& msg );
    void update_game_graph(float dummy ) ;
    void draw_can_go_region(sf::RenderTarget& target) ;
    void test_self_connection(float dummy, unsigned long id) ;
  public:
    void add_buddy(game_map_mover* buddy) {m_buddies.push_back(buddy) ;}
    void remove_buddy(game_map_mover* buddy) ;
    game_map_mover* current_valid_buddy() ;
    int tile_size()const {return m_tile_size ;}
    const pos_vec& get_valid_pos(){return m_valid ;}
    const pos_vec& get_processors() {return m_processors;}
    mover::position_type get_map_grid_position(size_t pos) ;
    mover::position_type get_map_grid_position(size_t x, size_t y) {
      return get_map_grid_position(y * m_width + x) ;
    }
  public:
    static const std::string LOAD_MAP_FROM_FILE ;
    static const std::string SET_TILE_SIZE ;
    static const std::string SET_TILE_IMAGE ;
    static const std::string FIX_ROAD ;
  } ;
}

#endif
